package com.liyuhan.onlinetaxibackground.Service.impl;

import com.google.gson.Gson;
import com.liyuhan.onlinetaxibackground.POJO.*;
import com.liyuhan.onlinetaxibackground.Repository.*;
import com.liyuhan.onlinetaxibackground.Service.UserService;
import com.liyuhan.onlinetaxibackground.Util.DateUtil;
import com.liyuhan.onlinetaxibackground.Util.GetRequestBody;
import com.liyuhan.onlinetaxibackground.Util.JedisPoolUtils;
import com.liyuhan.onlinetaxibackground.Util.TimeUtil;
import com.liyuhan.onlinetaxibackground.dto.DataRequest;
import com.liyuhan.onlinetaxibackground.dto.DataResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import redis.clients.jedis.Jedis;

import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.*;

@Service
public class UserImpl implements UserService {
    @Autowired
    private UserRepository userRepository;
    @Autowired
    private PassengerRepository passengerRepository;
    @Autowired
    private DriverRepository driverRepository;
    @Autowired
    private CompletedOrderRepository completedOrderRepository;
    @Autowired
    private CommentRepository commentRepository;

    // 响应参数
    private Map<String, String> map = new HashMap<>();

    @Override
    public DataResponse getUserInfo(String request) {
        DataRequest requestBody = GetRequestBody.getRequestBody(request);
        map.clear();

        String phone = requestBody.getData().get("phone").toString();

        User user = userRepository.findUserByPhone(phone).get();
        // 保留一位小数
        DecimalFormat df = new DecimalFormat("#.0");

        Long days = TimeUtil.daysBetween(new Date(), user.getRegisterDate());

        // 乘客获取信息
        if (user.getType().equals("passenger")) {
            Passenger passenger = passengerRepository.findPassengerByUser(user).get();

            // 获取用户使用日数和订单个数
            Integer numberOfOrders = completedOrderRepository.findCompletedOrdersByPassenger(passenger).get().size();

//            // 使用redis进行数据缓存
//            // 1.键的命名格式 -》 手机号+方法名+参数名
//            String numberOfOrdersKey = phone + "getUserInfo" + "numberOfOrders";
//            String numberOfUseDaysKey = phone + "getUserInfo" + "numberOfUseDays";
//            String scoreKey = phone + "getUserInfo" + "score";
//            Jedis jedis = JedisPoolUtils.getJedis();
//            // 2.判断redis中是否存在这些键
//            if (jedis.exists(numberOfOrdersKey)) {
//                // 键值对存在于jedis中
//                // 3.判断储存的数据是否仍然可用
//                if (jedis.get(numberOfOrdersKey).equals(numberOfOrders.toString()) || jedis.get(numberOfUseDaysKey).equals(days.toString())) {
//                    // 订单完成总数和用户使用时长都没变 -> 数据仍然有效 -> 从redis中提取数据进行返回
//                    map.put("numberOfOrders", jedis.get(numberOfOrdersKey));
//                    map.put("numberOfUseDays", jedis.get(numberOfUseDaysKey));
//                    map.put("score", jedis.get(scoreKey));
//
//                    return new DataResponse("200", map);
//                }
//            }

            // 设置乘客订单完成个数
            user.setNumberOfOrders(numberOfOrders);
            // 加入redis中
//            jedis.set(numberOfOrdersKey, String.valueOf(numberOfOrders));
            map.put("numberOfOrders", String.valueOf(numberOfOrders));

            // 设置乘客使用app天数
            user.setNumberOfUseDays(days + 1);
            // 加入redis中
//            jedis.set(numberOfUseDaysKey, String.valueOf(days));
            map.put("numberOfUseDays", String.valueOf(days + 1));

            // 设置乘客当前评分
            // 获取司机对当前乘客的全部评价（评价状态为1）
            List<Comment> comments = commentRepository.findCommentsByStateAndPassenger("1", passenger).get();
            double scoreCount = 0;
            for (Comment comment : comments) {
                scoreCount += comment.getScore();
            }
            // 评分保留小数点后一位
            String scoreStr = null;
            if (comments.size() == 0) {
                scoreStr = "5.0";
            } else {
                scoreStr = df.format(scoreCount / comments.size());
            }
            user.setScore(Double.valueOf(scoreStr));
            // 加入redis中
//            jedis.set(scoreKey, scoreStr);
            map.put("score", scoreStr);
        } else if (user.getType().equals("driver")) {
            Driver driver = driverRepository.findDriverByUser(user).get();

            // 获取用户使用日数和订单个数
            Integer numberOfOrders = completedOrderRepository.findCompletedOrdersByDriver(driver).get().size();

//            // 使用redis进行数据缓存
//            // 1.键的命名格式 -》 手机号+方法名+参数名
//            String numberOfOrdersKey = phone + "getUserInfo" + "numberOfOrders";
//            String numberOfUseDaysKey = phone + "getUserInfo" + "numberOfUseDays";
//            String scoreKey = phone + "getUserInfo" + "score";
//            Jedis jedis = JedisPoolUtils.getJedis();
//            // 2.判断redis中是否存在这些键
//            if (jedis.exists(numberOfOrdersKey)) {
//                // 键值对存在于jedis中
//                // 3.判断储存的数据是否仍然可用
//                if (jedis.get(numberOfOrdersKey).equals(numberOfOrders.toString()) || jedis.get(numberOfUseDaysKey).equals(days.toString())) {
//                    // 订单完成总数和用户使用时长都没变 -> 数据仍然有效 -> 从redis中提取数据进行返回
//                    map.put("numberOfOrders", jedis.get(numberOfOrdersKey));
//                    map.put("numberOfUseDays", jedis.get(numberOfUseDaysKey));
//                    map.put("score", jedis.get(scoreKey));
//
//                    return new DataResponse("200", map);
//                }
//            }

            // 设置司机订单完成个数
            user.setNumberOfOrders(numberOfOrders);
            // 加入redis中
//            jedis.set(numberOfOrdersKey, String.valueOf(numberOfOrders));
            map.put("numberOfOrders", String.valueOf(numberOfOrders));

            // 设置司机使用app天数
            user.setNumberOfUseDays(days + 1);
            // 加入redis中
//            jedis.set(numberOfUseDaysKey, String.valueOf(days));
            map.put("numberOfUseDays", String.valueOf(days + 1));

            // 设置司机当前评分
            // 获取乘客对当前司机的全部评价（评价状态为0）
            List<Comment> comments = commentRepository.findCommentsByStateAndDriver("0", driver).get();
            double scoreCount = 0;
            for (Comment comment : comments) {
                scoreCount += comment.getScore();
            }
            // 评分保留小数点后一位
            String scoreStr = null;
            if (comments.size() == 0) {
                scoreStr = "5.0";
            } else {
                scoreStr = df.format(scoreCount / comments.size());
            }
            user.setScore(Double.valueOf(scoreStr));
            // 加入redis中
//            jedis.set(scoreKey, scoreStr);
            map.put("score", scoreStr);
        }

        // 保存用户信息
        userRepository.save(user);

        // 返回结果
        return new DataResponse("200", map);
    }

    @Override
    public DataResponse getNickName(String request) {
        DataRequest requestBody = GetRequestBody.getRequestBody(request);
        map.clear();

        String phone = requestBody.getData().get("phone").toString();

        User user = userRepository.findUserByPhone(phone).get();

        String nickname = user.getNickname();

        if (nickname == null || nickname.equals("")) {
            map.put("nickname", "酷嘀用户" + user.getId());

            return new DataResponse("200", map);
        }

        map.put("nickname", nickname);

        return new DataResponse("200", map);
    }

    @Override
    public void saveUserBasicInfo(String request) {
        DataRequest requestBody = GetRequestBody.getRequestBody(request);

        String phone = requestBody.getData().get("phone").toString();

        String nickname = requestBody.getData().get("nickname").toString();
        String name = requestBody.getData().get("name").toString();
        String sex = requestBody.getData().get("sex").toString();
        String birthday = requestBody.getData().get("birthday").toString();
        String mail = requestBody.getData().get("mail").toString();

        User user = userRepository.findUserByPhone(phone).get();

        user.setNickname(nickname);
        user.setName(name);
        user.setSex(sex);
        if (birthday.equals("请选择您的生日")) {
            birthday = "";
        }
        user.setBirthday(birthday);
        user.setEmail(mail);

        userRepository.save(user);
    }

    @Override
    public DataResponse changePassword(String request) {
        DataRequest requestBody = GetRequestBody.getRequestBody(request);
        map.clear();

        String phone = requestBody.getData().get("phone").toString();
        String password = requestBody.getData().get("password").toString();
        String newPassword = requestBody.getData().get("newPassword").toString();

        User user = userRepository.findUserByPhone(phone).get();
        if (!user.getPassword().equals(password)) {
            // 原密码错误
            map.put("error", "您输入的原密码错误！");

            return new DataResponse("400", map);
        }

        user.setPassword(newPassword);

        userRepository.save(user);

        return new DataResponse("200", null);
    }

    @Override
    public DataResponse getUserBasicInfo(String request) {
        DataRequest requestBody = GetRequestBody.getRequestBody(request);
        map.clear();

        String phone = requestBody.getData().get("phone").toString();

        User user = userRepository.findUserByPhone(phone).get();

        String nickname = user.getNickname();
        String name = user.getName();
        String sex = user.getSex();
        String birthday = user.getBirthday();
        String email = user.getEmail();

        if (nickname == null) {
            nickname = "";
        }
        if (name == null) {
            name = "";
        }
        if (sex == null) {
            sex = "";
        }
        if (birthday == null) {
            birthday = "";
        }
        if (email == null) {
            email = "";
        }

        map.put("nickname", nickname);
        map.put("name", name);
        map.put("sex", sex);
        map.put("birthday", birthday);
        map.put("email", email);

        return new DataResponse("200", map);
    }

    @Override
    public DataResponse getWeeklyOrderCount(String request) {
        DataRequest requestBody = GetRequestBody.getRequestBody(request);

        String phone = requestBody.getData().get("phone").toString();

        User user = userRepository.findUserByPhone(phone).get();

        // 全部订单列表
        List<CompletedOrder> completedOrders = new ArrayList<>();

        if (user.getType().equals("passenger")) {
            Passenger passenger = passengerRepository.findPassengerByUser(user).get();
            // 获取全部已完成订单列表
            completedOrders.addAll(completedOrderRepository.findCompletedOrdersByPassengerAndState(passenger, "8").get());
            completedOrders.addAll(completedOrderRepository.findCompletedOrdersByPassengerAndState(passenger, "9").get());
        } else if (user.getType().equals("driver")) {
            Driver driver = driverRepository.findDriverByUser(user).get();
            // 获取全部订单
            completedOrders.addAll(completedOrderRepository.findCompletedOrdersByDriverAndState(driver, "8").get());
            completedOrders.addAll(completedOrderRepository.findCompletedOrdersByDriverAndState(driver, "9").get());
        }


        int count1 = 0, count2 = 0, count3 = 0, count4 = 0, count5 = 0, count6 = 0, count7 = 0;

        for (CompletedOrder completedOrder : completedOrders) {
            if (completedOrder.getArriveTime() != null) {
                if (DateUtil.isSameDay(completedOrder.getArriveTime(), DateUtil.subtractDays(new Date(), 7))) {
                    count7++;
                } else if (DateUtil.isSameDay(completedOrder.getArriveTime(), DateUtil.subtractDays(new Date(), 6))) {
                    count6++;
                } else if (DateUtil.isSameDay(completedOrder.getArriveTime(), DateUtil.subtractDays(new Date(), 5))) {
                    count5++;
                } else if (DateUtil.isSameDay(completedOrder.getArriveTime(), DateUtil.subtractDays(new Date(), 4))) {
                    count4++;
                } else if (DateUtil.isSameDay(completedOrder.getArriveTime(), DateUtil.subtractDays(new Date(), 3))) {
                    count3++;
                } else if (DateUtil.isSameDay(completedOrder.getArriveTime(), DateUtil.subtractDays(new Date(), 2))) {
                    count2++;
                } else if (DateUtil.isSameDay(completedOrder.getArriveTime(), DateUtil.subtractDays(new Date(), 1))) {
                    count1++;
                }
            }
        }

        List<Integer> countList = new ArrayList<>();
        countList.add(count1);
        countList.add(count2);
        countList.add(count3);
        countList.add(count4);
        countList.add(count5);
        countList.add(count6);
        countList.add(count7);

        // 格式转化工具
        Gson gson = new Gson();
        SimpleDateFormat formatter = new SimpleDateFormat("MM-dd");

        // 日期列表
        List<String> orderCountKey = new ArrayList<>();
        List<Double> orderCountValue = new ArrayList<>();

        for (int i = 7; i > 0; i--) {
            // 放入日期
            orderCountKey.add(formatter.format(DateUtil.subtractDays(new Date(), i)));
            orderCountValue.add(Double.valueOf(countList.get(i - 1)));
        }

        map.put("orderCountKey", gson.toJson(orderCountKey));
        map.put("orderCountValue", gson.toJson(orderCountValue));

        return new DataResponse("200", map);
    }

    @Override
    public DataResponse getWeeklyCostCount(String request) {
        DataRequest requestBody = GetRequestBody.getRequestBody(request);

        String phone = requestBody.getData().get("phone").toString();

        User user = userRepository.findUserByPhone(phone).get();
        Passenger passenger = passengerRepository.findPassengerByUser(user).get();

        // 获取全部已完成订单列表
        List<CompletedOrder> completedOrders = completedOrderRepository.findCompletedOrdersByPassengerAndState(passenger, "8").get();
        completedOrders.addAll(completedOrderRepository.findCompletedOrdersByPassengerAndState(passenger, "9").get());

        Double count1 = 0.0, count2 = 0.0, count3 = 0.0, count4 = 0.0, count5 = 0.0, count6 = 0.0, count7 = 0.0;

        for (CompletedOrder completedOrder : completedOrders) {
            if (completedOrder.getPay() != null && completedOrder.getArriveTime() != null) {
                if (DateUtil.isSameDay(completedOrder.getArriveTime(), DateUtil.subtractDays(new Date(), 7))) {
                    count7 += completedOrder.getPay();
                } else if (DateUtil.isSameDay(completedOrder.getArriveTime(), DateUtil.subtractDays(new Date(), 6))) {
                    count6 += completedOrder.getPay();
                } else if (DateUtil.isSameDay(completedOrder.getArriveTime(), DateUtil.subtractDays(new Date(), 5))) {
                    count5 += completedOrder.getPay();
                } else if (DateUtil.isSameDay(completedOrder.getArriveTime(), DateUtil.subtractDays(new Date(), 4))) {
                    count4 += completedOrder.getPay();
                } else if (DateUtil.isSameDay(completedOrder.getArriveTime(), DateUtil.subtractDays(new Date(), 3))) {
                    count3 += completedOrder.getPay();
                } else if (DateUtil.isSameDay(completedOrder.getArriveTime(), DateUtil.subtractDays(new Date(), 2))) {
                    count2 += completedOrder.getPay();
                } else if (DateUtil.isSameDay(completedOrder.getArriveTime(), DateUtil.subtractDays(new Date(), 1))) {
                    count1 += completedOrder.getPay();
                }
            }
        }

        List<Double> countList = new ArrayList<>();
        countList.add(count1);
        countList.add(count2);
        countList.add(count3);
        countList.add(count4);
        countList.add(count5);
        countList.add(count6);
        countList.add(count7);

        // 格式转化工具
        Gson gson = new Gson();
        SimpleDateFormat formatter = new SimpleDateFormat("MM-dd");

        // 日期列表
        List<String> costCountKey = new ArrayList<>();
        List<Double> costCountValue = new ArrayList<>();

        for (int i = 7; i > 0; i--) {
            // 放入日期
            costCountKey.add(formatter.format(DateUtil.subtractDays(new Date(), i)));
            costCountValue.add(Double.valueOf(countList.get(i - 1)));
        }

        map.put("costCountKey", gson.toJson(costCountKey));
        map.put("costCountValue", gson.toJson(costCountValue));

        return new DataResponse("200", map);
    }

    @Override
    public DataResponse getWeeklyIncomeCount(String request) {
        DataRequest requestBody = GetRequestBody.getRequestBody(request);

        String phone = requestBody.getData().get("phone").toString();

        User user = userRepository.findUserByPhone(phone).get();
        Driver driver = driverRepository.findDriverByUser(user).get();

        // 获取全部已完成订单列表
        List<CompletedOrder> completedOrders = completedOrderRepository.findCompletedOrdersByDriverAndState(driver, "8").get();
        completedOrders.addAll(completedOrderRepository.findCompletedOrdersByDriverAndState(driver, "9").get());

        Double count1 = 0.0, count2 = 0.0, count3 = 0.0, count4 = 0.0, count5 = 0.0, count6 = 0.0, count7 = 0.0;

        for (CompletedOrder completedOrder : completedOrders) {
            if (completedOrder.getPay() != null && completedOrder.getArriveTime() != null) {
                if (DateUtil.isSameDay(completedOrder.getArriveTime(), DateUtil.subtractDays(new Date(), 7))) {
                    count7 += completedOrder.getPay();
                } else if (DateUtil.isSameDay(completedOrder.getArriveTime(), DateUtil.subtractDays(new Date(), 6))) {
                    count6 += completedOrder.getPay();
                } else if (DateUtil.isSameDay(completedOrder.getArriveTime(), DateUtil.subtractDays(new Date(), 5))) {
                    count5 += completedOrder.getPay();
                } else if (DateUtil.isSameDay(completedOrder.getArriveTime(), DateUtil.subtractDays(new Date(), 4))) {
                    count4 += completedOrder.getPay();
                } else if (DateUtil.isSameDay(completedOrder.getArriveTime(), DateUtil.subtractDays(new Date(), 3))) {
                    count3 += completedOrder.getPay();
                } else if (DateUtil.isSameDay(completedOrder.getArriveTime(), DateUtil.subtractDays(new Date(), 2))) {
                    count2 += completedOrder.getPay();
                } else if (DateUtil.isSameDay(completedOrder.getArriveTime(), DateUtil.subtractDays(new Date(), 1))) {
                    count1 += completedOrder.getPay();
                }
            }
        }

        List<Double> countList = new ArrayList<>();
        countList.add(count1);
        countList.add(count2);
        countList.add(count3);
        countList.add(count4);
        countList.add(count5);
        countList.add(count6);
        countList.add(count7);

        // 格式转化工具
        Gson gson = new Gson();
        SimpleDateFormat formatter = new SimpleDateFormat("MM-dd");

        // 日期列表
        List<String> incomeCountKey = new ArrayList<>();
        List<Double> incomeCountValue = new ArrayList<>();

        for (int i = 7; i > 0; i--) {
            // 放入日期
            incomeCountKey.add(formatter.format(DateUtil.subtractDays(new Date(), i)));
            incomeCountValue.add(Double.valueOf(countList.get(i - 1)));
        }

        map.put("incomeCountKey", gson.toJson(incomeCountKey));
        map.put("incomeCountValue", gson.toJson(incomeCountValue));

        return new DataResponse("200", map);
    }

    @Override
    public DataResponse getWeeklyTaxiLocation(String request) {
        // 获取本周完成订单地点的统计数据
        DataRequest requestBody = GetRequestBody.getRequestBody(request);

        String phone = requestBody.getData().get("phone").toString();

        User user = userRepository.findUserByPhone(phone).get();
        Passenger passenger = passengerRepository.findPassengerByUser(user).get();

        // 获取全部已完成订单列表
        List<CompletedOrder> completedOrders = completedOrderRepository.findCompletedOrdersByPassengerAndState(passenger, "8").get();
        completedOrders.addAll(completedOrderRepository.findCompletedOrdersByPassengerAndState(passenger, "9").get());

        Map<String, Integer> countMap = new HashMap<>();

        for (CompletedOrder completedOrder : completedOrders) {
            if (completedOrder.getArriveTime() != null) {
                if (DateUtil.isBetween(DateUtil.subtractDays(new Date(), 7), DateUtil.subtractDays(new Date(), 1), completedOrder.getArriveTime())) {
                    String startInfo = completedOrder.getReceivedOrder().getOrder().getStartInfo();
                    if (countMap.containsKey(startInfo)) {
                        countMap.put(startInfo, countMap.get(startInfo) + 1);
                    } else {
                        countMap.put(startInfo, 1);
                    }
                }
            }
        }

        // 格式转化工具
        Gson gson = new Gson();

        // 日期列表
        List<String> taxiLocationKey = new ArrayList<>();
        List<Double> taxiLocationValue = new ArrayList<>();

        Set<String> strings = countMap.keySet();
        Iterator<String> iterator = strings.iterator();


        while (iterator.hasNext()) {
            // 放入日期
            String key = iterator.next();
            taxiLocationKey.add(key);
            taxiLocationValue.add(Double.valueOf(countMap.get(key)));
        }

        map.put("taxiLocationKey", gson.toJson(taxiLocationKey));
        map.put("taxiLocationValue", gson.toJson(taxiLocationValue));

        return new DataResponse("200", map);
    }

    @Override
    public DataResponse getWeeklyOrderType(String request) {
        // 获取本周完成订单地点的统计数据
        DataRequest requestBody = GetRequestBody.getRequestBody(request);

        String phone = requestBody.getData().get("phone").toString();

        User user = userRepository.findUserByPhone(phone).get();
        Driver driver = driverRepository.findDriverByUser(user).get();

        // 获取全部已完成订单列表
        List<CompletedOrder> completedOrders = completedOrderRepository.findCompletedOrdersByDriverAndState(driver, "8").get();
        completedOrders.addAll(completedOrderRepository.findCompletedOrdersByDriverAndState(driver, "9").get());

        Integer rightNowCount = 0, reservationCount = 0;

        for (CompletedOrder completedOrder : completedOrders) {
            if (completedOrder.getArriveTime() != null) {
                if (DateUtil.isBetween(DateUtil.subtractDays(new Date(), 7), DateUtil.subtractDays(new Date(), 1), completedOrder.getArriveTime())) {
                    if (completedOrder.getReceivedOrder().getOrder().getUseCarType().equals("实时单")) {
                        rightNowCount++;
                    } else if (completedOrder.getReceivedOrder().getOrder().getUseCarType().equals("预约单")) {
                        reservationCount++;
                    }
                }
            }
        }

        // 格式转化工具
        Gson gson = new Gson();

        // 日期列表
        List<String> orderTypeKey = new ArrayList<>();
        List<Double> orderTypeValue = new ArrayList<>();

        orderTypeKey.add("实时单");
        orderTypeKey.add("预约单");
        orderTypeValue.add(Double.valueOf(rightNowCount));
        orderTypeValue.add(Double.valueOf(reservationCount));

        map.put("orderTypeKey", gson.toJson(orderTypeKey));
        map.put("orderTypeValue", gson.toJson(orderTypeValue));

        return new DataResponse("200", map);
    }
}
